{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Getting started: Machine learning with differential privacy in 30 seconds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We're using the [Iris dataset](https://archive.ics.uci.edu/ml/datasets/iris), so let's load it and perform an 80/20 train/test split."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "dataset = datasets.load_iris()\n",
    "X_train, X_test, y_train, y_test = train_test_split(dataset.data, dataset.target, test_size=0.2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, let's train a differentially private naive Bayes classifier. Our classifier __runs just like an `sklearn` classifier__, so you can get up and running quickly.\n",
    "\n",
    "`diffprivlib.models.GaussianNB` can be run __without any parameters__, although this will throw a warning (we need to specify the `bounds` parameter to avoid this). The privacy level is controlled by the parameter `epsilon`, which is passed to the classifier at initialisation (e.g. `GaussianNB(epsilon=0.1)`). The default is `epsilon = 1.0`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      ".../site-packages/diffprivlib/models/naive_bayes.py:102: PrivacyLeakWarning: Bounds have not been specified and will be calculated on the data provided. This will result in additional privacy leakage. To ensure differential privacy and no additional privacy leakage, specify bounds for each dimension.\n",
      "  \"privacy leakage, specify bounds for each dimension.\", PrivacyLeakWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "GaussianNB(accountant=BudgetAccountant(spent_budget=[(1.0, 0)]),\n",
       "           bounds=(array([4.3, 2. , 1.1, 0.1]), array([7.9, 4.4, 6.9, 2.5])))"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from diffprivlib.models import GaussianNB\n",
    "\n",
    "clf = GaussianNB()\n",
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can now classify unseen examples, knowing that the trained model is differentially private and preserves the privacy of the 'individuals' in the training set (flowers are entitled to their privacy too!)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 1, 0, 2, 1, 1, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 1,\n",
       "       1, 0, 0, 2, 1, 2, 1, 1])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Every time the model is trained with `.fit()`, a different model is produced due to the randomness of differential privacy. The accuracy will therefore change, even if it's re-trained with the same training data. Try it for yourself to find out!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test accuracy: 0.833333\n"
     ]
    }
   ],
   "source": [
    "print(\"Test accuracy: %f\" % clf.score(X_test, y_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can easily evaluate the accuracy of the model for various `epsilon` values and plot it with `matplotlib`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "epsilons = np.logspace(-2, 2, 50)\n",
    "bounds = ([4.3, 2.0, 1.1, 0.1], [7.9, 4.4, 6.9, 2.5])\n",
    "accuracy = list()\n",
    "\n",
    "for epsilon in epsilons:\n",
    "    clf = GaussianNB(bounds=bounds, epsilon=epsilon)\n",
    "    clf.fit(X_train, y_train)\n",
    "    \n",
    "    accuracy.append(clf.score(X_test, y_test))\n",
    "\n",
    "plt.semilogx(epsilons, accuracy)\n",
    "plt.title(\"Differentially private Naive Bayes accuracy\")\n",
    "plt.xlabel(\"epsilon\")\n",
    "plt.ylabel(\"Accuracy\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Congratulations, you've completed your first differentially private machine learning task with the Differential Privacy Library!  Check out more examples in the [notebooks](./) directory, or [dive straight in](../diffprivlib/)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
